package com.zeratul.common.dubbo.filter;

import cn.hutool.core.util.ObjectUtil;
import com.zeratul.common.core.constant.RemoteConstants;
import com.zeratul.common.core.context.DataContextHolde;
import com.zeratul.common.json.utils.JsonUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.slf4j.MDC;
import org.springframework.core.Ordered;

import java.util.Map;

/**
 * Dubbo上下文数据传递过滤器
 *
 * 用于在Dubbo请求之前，将调用方服务的链路上下文数据传递给被调用方
 */
@Activate(group = {CommonConstants.CONSUMER}, order = Ordered.HIGHEST_PRECEDENCE + 100)
public class DubboContextConsumerFilter implements Filter {


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        //获取链路上下文
        Map<String, Object> traceContext = DataContextHolde.getTraceContextOnCopy();
        if (ObjectUtil.isNotEmpty(traceContext)) {
            invocation.setAttachment(RemoteConstants.TRACE_CONTEXT, JsonUtils.serialize(traceContext));
        }

        //获取MDC
        Map<String, String> mdc = MDC.getCopyOfContextMap();
        if (ObjectUtil.isNotEmpty(mdc)) {
            invocation.setAttachment(RemoteConstants.MDC, JsonUtils.serialize(mdc));
        }

        //执行Dubbo调用逻辑并返回结果
        return invoker.invoke(invocation);
    }
}
